package com.klangner.atarigo.ai.moveselector;

import java.util.Collection;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.Vector;

import com.klangner.game.ai.ab.IMoveSelector;
import com.klangner.game.board.BoardPosition;
import com.klangner.game.board.IBoard;
import com.klangner.game.board.Move;
import com.klangner.go.app.rules.BoardModel;
import com.klangner.go.app.rules.GobanLocation;
import com.klangner.go.app.rules.StonesGroupOld;


/**
 * Selects all neighbourhood stones
 * 
 * @author Krzysztof Langner
 * @version 1.0
 */
public class NeighbourhoodMoveSelector implements IMoveSelector{

	private int stoneColor;
	
  //----------------------------------------------------------------------------
  /**
   * @see IMoveSelector#getCandidates(IBoard, int)
   */
    public List<Move> getCandidates( BoardModel board, int color ) {

    	this.stoneColor = color;
      Vector<Move> candidateMoves = new Vector<Move>();

      // Select as possible next moves just the contact moves
      // Not as a best strategy :-) but as a reasonable filtering method
      Collection<Move> contactMoves = getContactMoves(board);

      Iterator<Move> it;
      if (!contactMoves.isEmpty()) {
      	it = contactMoves.iterator();
      }
      else{
      	// get all legal moves
      	it = board.legalMoves();
      }

      while( it.hasNext() ) {
      	BoardPosition gl = it.next();
        Move move = new Move(gl.getX(), gl.getY(), board.getTurnColor());

        candidateMoves.addElement( move );
      }

      return candidateMoves;
    }


  //----------------------------------------------------------------------------
  // returns an iterator with the possible contact moves
  private Collection<Move> getContactMoves(BoardModel board) {

    Enumeration<StonesGroupOld> 	blackGroups, whiteGroups;
    Set<GobanLocation> 				result;
    Vector<Move>							moves = new Vector<Move>();

    result = new HashSet<GobanLocation>();

    whiteGroups = board.getWhiteGroups().elements();
    blackGroups = board.getBlackGroups().elements();

    // add black groups' liberties to the list
    for (;blackGroups.hasMoreElements();) {
      // get current group's liberties
      result.addAll((blackGroups.nextElement()).getLiberties());
    }

    // add white groups' liberties to the list
    for (;whiteGroups.hasMoreElements();) {
      // get current group's liberties
      result.addAll((whiteGroups.nextElement()).getLiberties());
    }

    Iterator<GobanLocation>	it = result.iterator();
    while( it.hasNext() ){
    	GobanLocation gl = it.next();
    	Move move = new Move(gl.x, gl.y, stoneColor);
    	if( board.isLegalMove(move) )
    		moves.add(move);
    }
    
    return moves;

  }

}